﻿/*
 *	Copyright (c) 2009 Queensland University of Technology. All rights reserved.
 *	The QUT Bioinformatics Collection is open source software released under the 
 *	Microsoft Public License (Ms-PL): http://www.microsoft.com/opensource/licenses.mspx.
 */
using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace QUT.Bio.Util {
	/// <summary>
	/// An efficient general purpose lookup table, based on a Dictionary.
	/// Silverlight does not supply this class out of the box.
	/// </summary>
	/// <typeparam name="T">the type of objects to be stored in the HashList.</typeparam>
	
	public class HashList<T>: IEnumerable<T> {
		private readonly Dictionary<T, T> items = new Dictionary<T, T>();

		/// <summary>
		/// Returns true iff an item matching the supplied key is present in the collection.
		/// </summary>
		/// <param name="key">The key to look up in the collection.</param>
		/// <returns>See summary.</returns>
		
		public bool Contains ( T key ) {
			return items.ContainsKey( key );
		}

		/// <summary>
		/// If the item to add is not present in the collection, the supplied item
		/// is added to the collection and the supplied item is returned.
		/// <para>
		///		If the collection already contains an item that matches the supplied item,
		///		the matching item already present in the collection is returned.
		/// </para>
		/// </summary>
		/// <param name="itemToAdd">An item to add or look up in the collection.</param>
		/// <returns>See summary.</returns>
		
		public T Add ( T itemToAdd ) {
			if ( ! items.ContainsKey( itemToAdd ) ) {
				items[itemToAdd] = itemToAdd;
				return itemToAdd;
			}
			else {
				return items[itemToAdd];
			}
		}
		
		/// <summary>
		/// Gets the stored instance that equals the supplied key, or returns the default value
		/// if no match for the key is found.
		/// </summary>
		/// <param name="key">The key to look up.</param>
		/// <returns>The stored instance that matches key, or default.</returns>
		
		public T Get( T key ) {
			if ( items.ContainsKey( key ) ) {
				return items[key];
			}
			else {
				return default(T);
			}
		}

		/// <summary>
		/// Removes the nominated item t from this hashlist.
		/// <para>
		///		If t is not present in the list, no change is effected.
		/// </para>
		/// </summary>
		/// <param name="itemToRemove">An item to remove from the list.</param>

		public void Remove ( T itemToRemove ) {
			if ( items.ContainsKey( itemToRemove ) ) {
				items.Remove( itemToRemove );
			}
		}

		/// <summary>
		/// Gets a strongly typed enumerator that traverses the collection.
		/// </summary>
		/// <returns></returns>

		public IEnumerator<T> GetEnumerator () {
			return items.Keys.GetEnumerator();
		}

		/// <summary>
		/// Get an enumerator that traverses the collection.
		/// </summary>
		/// <returns></returns>
		
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () {
			return items.Keys.GetEnumerator();
		}
		
		/// <summary>
		/// Gets the number of elements in the collection.
		/// </summary>
		
		public int Count {
			get {
				return items.Count;
			}
		}
		
		/// <summary>
		/// Removes all items from the collection.
		/// </summary>
		
		public void Clear() {
			items.Clear();
		}
		
		/// <summary>
		/// Adds all items in the supplied collection to the hash list, via the Add method.
		/// </summary>
		/// <param name="collection">A list of items to add.</param>
		
		public void AddRange( IEnumerable<T> collection ) {
			foreach ( T element in collection ) {
				Add( element );
			}
		}
	}
}
